package com.mdp.tpa.wechat.service;

import java.util.HashMap;
import java.util.Map;

import com.mdp.tpa.wechat.api.SecurityService;
import com.mdp.tpa.wechat.config.WxpubProperties;
import com.mdp.tpa.wechat.util.WxaSecurityUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.mdp.core.err.BizException;

import qq.weixin.mp.aes.AesException;
import qq.weixin.mp.aes.WXBizMsgCrypt;

@Service
public class SecurityServiceImpl implements SecurityService {
	
	 
	Log log=LogFactory.getLog(SecurityServiceImpl.class);
	   
	Map<String,WXBizMsgCrypt> wxcptMap=new HashMap<>();

	@Autowired
    WxpubProperties properties;
			
 
	/****
	 * 首次服务器验证 微信发过来的信息
	 * {timestamp=1478231323, echostr=2293813022107307999, nonce=320121891, signature=ef7a44ee63872eef9aeb01e5a26f7ed13f216eef}
	 */
	public String verifyUrl(String msgSignature, String timeStamp, String nonce, String echoStr) {
		String echoStrMingWen;
		try {
			WXBizMsgCrypt cry=wxcptMap.get(properties.getAppid());
			if(cry==null) {
				cry=this.initCry();
			}
			if(cry==null) {
				throw new BizException("加密工具未加载成功");
			}
			echoStrMingWen = cry.verifyUrl(msgSignature, timeStamp, nonce, echoStr);
		} catch (AesException e) {
			 throw new BizException("WxApiSecurity43", e.getMessage());
		}
		if(log.isDebugEnabled()){
			log.debug("收到微信公众平台解密后消息："+echoStrMingWen);
		} 
		return echoStrMingWen; 
	}
	/**
	 * 检验消息的真实性，并且获取解密后的明文.
	 * <ol>
	 * 	<li>利用收到的密文生成安全签名，进行签名验证</li>
	 * 	<li>若验证通过，则提取xml中的加密消息</li>
	 * 	<li>对消息进行解密</li>
	 * </ol>
	 * 
	 * @param msgSignature 签名串，对应URL参数的msg_signature
	 * @param timeStamp 时间戳，对应URL参数的timestamp
	 * @param nonce 随机串，对应URL参数的nonce
	 * @param postData 密文，对应POST请求的数据
	 * 
	 * @return 解密后的原文
	 * @throws AesException 执行失败，请查看该异常的错误码和具体的错误信息
	 */
	public String decryptMsg( String msgSignature, String timeStamp, String nonce, String postData){
		try {
			WXBizMsgCrypt cry=wxcptMap.get(properties.getAppid());
			if(cry==null) {
				cry=this.initCry( );
			}
			if(cry==null) {
				throw new BizException("加密工具未加载成功");
			}
			return  cry.decryptMsg(msgSignature, timeStamp, nonce, postData);
		} catch (AesException e) {
			 log.error("",e);
			 throw new BizException("WxmsgService53","解密失败");
		}
	}
	@Override
	public Map<String, Object> decryptPhoneNo(String sessionKey, String encryptedData, String iv) {
		// TODO Auto-generated method stub
		return WxaSecurityUtil.decrypt(sessionKey, encryptedData, iv);
	}
		   
	WXBizMsgCrypt initCry( ){
		try {
				try {
					WXBizMsgCrypt wxcpt=new WXBizMsgCrypt(properties.getAppToken(),properties.getEncKey(), properties.getAppid());
					wxcptMap.put(properties.getAppid(), wxcpt);
					return wxcpt;
				} catch (Exception e) {
					log.error("自动初始化微信消息加解密算法工具失败 ,第三方应用编号【"+properties.getAppid()+"】");
				} 
		} catch (Exception e) {
			log.error("自动初始化微信消息加解密算法工具失败");   
		}
		return null;
		
	}
	@Override
	public void clearCache( ) {
		wxcptMap.clear();
		
	}
	 
	
}
